const webDataUtil = require('../../util/webDataUtil')
const reqlib = require('app-root-path').require
const btbAs = reqlib('/app/common/btb')
const commonDataCreate = require('./utils/commonDataCreate')
const AnalysisInfoFlag = reqlib('/app/analysis/analysisInfoFlag')
const Proxy = require('../../proxy')
const BuySellMachine = reqlib('/app/analysis/buySellMachine')
const AccountMachine = reqlib('/app/analysis/accountMachine')
const Performance = reqlib('/app/common/performance')

const Dictionary = Proxy.Dictionary
const BtbIndex = Proxy.BtbIndex
const QuoteVolumeProxy = Proxy.QuoteVolume

const getWithKlineList = async (item) => {
  const key = item.code
  const klineResult = await Promise.all([
    webDataUtil.getFuturesKLinesAll({
      name: `${key}`,
      interval: '15m',
      count: 500
    }),
    webDataUtil.getFuturesKLinesAll({
      name: `${key}`,
      interval: '1h',
      count: 500
    }),
    webDataUtil.getFuturesKLinesAll({
      name: `${key}`,
      interval: '4h',
      count: 500
    }),
    webDataUtil.getFuturesKLinesAll({
      name: `${key}`,
      interval: '1d',
      count: 500
    })
  ])
  item.symbol = `${item.code}USDT`
  item.min_qty = item.f_min_qty
  item.max_qty = item.f_max_qty
  item.step_size = item.f_step_size
  item.min_notional = item.f_min_notional
  item.tick_size = item.f_tick_size
  item.klineList15m = klineResult[0]
  item.klineList1h = klineResult[1]
  item.klineList4h = klineResult[2]
  item.klineList1d = klineResult[3]
}

const analysisBtbItem = (item) => {
  const p = new Performance()
  p.start()
  // 慢是因为分析2000天的，10个就20000天
  item.analysisInfoList15m = btbAs.getItemInfoList(item.klineList15m)
  item.analysisInfoList1h = btbAs.getItemInfoList(item.klineList1h)
  item.analysisInfoList4h = btbAs.getItemInfoList(item.klineList4h)
  item.analysisInfoList1d = btbAs.getItemInfoList(item.klineList1d)
  p.print(`分析结束`)
  // 都转为从近到远
  item.analysisInfoList15m.reverse()
  item.analysisInfoList1h.reverse()
  item.analysisInfoList4h.reverse()
  item.analysisInfoList1d.reverse()
  item.analysisInfoList15m.forEach((v, index) => {
    commonDataCreate.asInfoExtend(item.analysisInfoList15m, v, index)
  })
  item.analysisInfoList1h.forEach((v, index) => {
    commonDataCreate.asInfoExtend(item.analysisInfoList1h, v, index)
  })
  item.analysisInfoList4h.forEach((v, index) => {
    commonDataCreate.asInfoExtend(item.analysisInfoList4h, v, index)
  })
  item.analysisInfoList1d.forEach((v, index) => {
    commonDataCreate.asInfoExtend(item.analysisInfoList1d, v, index)
  })
  p.print(`扩展结束`)
  item.klineList15m.reverse()
  item.klineList1h.reverse()
  item.klineList4h.reverse()
  item.klineList1d.reverse()
  item.analysisInfoFlag15m = new AnalysisInfoFlag({
    analysisInfoList: item.analysisInfoList15m,
    type: '15m',
    code: item.code
  })
  item.close = item.analysisInfoFlag15m.nowEmaInfo.close
  item.analysisInfoFlag1h = new AnalysisInfoFlag({
    analysisInfoList: item.analysisInfoList1h,
    type: '1h',
    code: item.code
  })
  item.analysisInfoFlag4h = new AnalysisInfoFlag({
    analysisInfoList: item.analysisInfoList4h,
    type: '4h',
    code: item.code
  })
  item.analysisInfoFlag1d = new AnalysisInfoFlag({
    analysisInfoList: item.analysisInfoList1d,
    type: '1d',
    code: item.code
  })
  p.print(`建模结束`)
}

const getDictionaryInfo = async () => {
  const preFind = await Dictionary.findOne({
    key: 'preFindBtbResult'
  })
  let preFindBtbResult = {}
  if (preFind) {
    try {
      preFindBtbResult = JSON.parse(preFind.value)
    } catch (e) {
      preFindBtbResult = {}
    }
  }
  // 仓位配置
  let btbPositionConfigRes = await Dictionary.findOne({ key: 'btbPositionConfig' })
  let btbPositionConfig = (btbPositionConfigRes && btbPositionConfigRes.value) || 100
  if (btbPositionConfig !== '自动') {
    btbPositionConfig = parseInt(btbPositionConfig) || 100
    btbPositionConfig = btbPositionConfig / 100
  } else {
    btbPositionConfig = preFindBtbResult.positionConfig || 0.5
  }
  return {
    preFindBtbResult,
    btbPositionConfig
  }
}

const getRecentMarketInfo = async () => {
  const list = await QuoteVolumeProxy.find({}, {
    skip: 0,
    limit: 200,
    sort: '-time'
  }) || []
  return list.map((v) => {
    const detail = v.detail || {}
    return {
      ...detail
    }
  })
}

module.exports = async function (params) {
  let item = await BtbIndex.findOne({
    code: params.code
  })
  if (!item) {
    item = {
      code: params.code
    }
  }
  const dictionaryInfo = await getDictionaryInfo()
  const marketInfoList = await getRecentMarketInfo()
  let preFindBtbResult = dictionaryInfo.preFindBtbResult
  let btbPositionConfig = dictionaryInfo.btbPositionConfig
  await getWithKlineList(item)
  analysisBtbItem(item)
  const accountMachine = new AccountMachine({
    btbCount: 10,
    positionConfig: btbPositionConfig,
    marketInfoList: marketInfoList || []
  })
  await accountMachine.refresh()
  const symbolAccount = accountMachine.getBtbItemAccount(item.symbol)
  const futuresAccount = accountMachine.getFuturesAccount()
  item.buySellMachine = new BuySellMachine({
    realBuySell: true,
    btbItem: item,
    symbolAccount,
    futuresAccount,
    BtbIndexProxy: {},
    marketInfo: preFindBtbResult,
    marketInfoList: marketInfoList || []
  })
  // 执行
  item.buySellMachine.execute()
  const info = {
    ...item.buySellMachine.getBuySellConfigInfo(),
    ...item.buySellMachine.getQuantityParams(),
    ...(item.buySellMachine.marketFlagInfo || {}),
    ...(item.buySellMachine.indexFlagInfo || {})
  }
  return {
    ...info,
    preFindBtbResult
  }
}
